package com.synjones.ui;

import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.DialogInterface;
import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.ActionMode;
import android.view.Display;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.synjones.AppExecutors;
import com.synjones.config.Config;
import com.synjones.entry.SignPerson;
import com.synjones.idcardusb_reader.R;
import com.synjones.printer.billPrinter.BillPrinter;
import com.synjones.ui.check.CheckFragment;
import com.synjones.ui.lunch.LunchFragment;
import com.synjones.ui.others.OthersFragment;
import com.synjones.ui.recognize.RecognizeFragment;
import com.synjones.ui.secondScreen.SecondScreen;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements FirstScreenRouter {

    private final int jumpDelay = 1500;

    private final String  TAG_WELCOME_FRAGMENT = "TAG_WELCOME_FRAGMENT";
    private final String  TAG_CHECK_FRAGMENT = "TAG_CHECK_FRAGMENT";
    private final String  TAG_OTHERS_FRAGMENT = "TAG_OTHERS_FRAGMENT";
    private FragmentManager fragmentManager;

    private TextView toastTextView;

    private RecognizeFragment recognizeFragment;

    private BillPrinter billPrinter = new BillPrinter(this);
    private FirstScreenRouter router1 = this;
    private SecondScreenRouter router2;
    private SecondScreen secondScreen;
    private View settings;
    private ActionMode actionMode;



    private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.settings,menu);
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        // Called when the user selects a contextual menu item
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()){
                case R.id.togglePrinter:
                    new AlertDialog.Builder(MainActivity.this)
                            .setMessage("开启/关闭打印")
                            .setPositiveButton("开启", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                    Config.openPrinter(true);
                                }
                            })
                            .setNegativeButton("关闭", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                    Config.openPrinter(false);
                                }
                            })
                            .show();
                    return  true;
                case R.id.setIP:
                    LinearLayout inputIPContainer;
                    final EditText inputIP;
                    inputIPContainer = new LinearLayout(MainActivity.this);
                    inputIPContainer.setPadding(8,0,8,0);
                    inputIP = new EditText(MainActivity.this);
                    inputIPContainer.addView(inputIP,
                            new LinearLayout.LayoutParams(
                                    ViewGroup.LayoutParams.MATCH_PARENT,
                                    ViewGroup.LayoutParams.MATCH_PARENT));
                    inputIP.setText(Config.getConfigIp());
                    new AlertDialog.Builder(MainActivity.this)
                            .setView(inputIPContainer)
                            .setPositiveButton("保存", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                    Config.setConfigIp(inputIP.getText().toString());
                                }
                            })
                            .show();
                    return  true;
                case R.id.listSettings:
                    String info = "打印机状态 -> " + (Config.openedPrinter() ? "开启" : "关闭")+"\n";
                    info += "打印服务器IP -> " + Config.getConfigIp();
                    new AlertDialog.Builder(MainActivity.this)
                            .setMessage(info)
                            .setPositiveButton("确定", null)
                            .show();
                    return true;
                default:
                    return false;
            }
        }

        // Called when the user exits the action mode
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            actionMode = null;
        }
    };


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toastTextView = (TextView) findViewById(R.id.toastTextView);
        settings = findViewById(R.id.settings);
        initBillPrinter();
        initFragment();
        initSecondScreen(this);
        setView();
    }


    private void initFragment(){
        recognizeFragment = new RecognizeFragment();
        fragmentManager = getSupportFragmentManager();
        fragmentManager
                .beginTransaction()
                .add(R.id.fragContainer,recognizeFragment)
                .commit();
        fragmentManager
                .beginTransaction()
                .add(R.id.fragContainer,new LunchFragment(),TAG_WELCOME_FRAGMENT)
                .commit();
    }

    private void initBillPrinter(){
        AppExecutors.ioExecutor.execute(new Runnable() {
            @Override
            public void run() { if (billPrinter.connectPrinterService()) billPrinter.connectDevice(); }
        });

    }

    private void setView(){
        settings.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                if (actionMode != null) {
                    return false;
                }
                actionMode = startActionMode(actionModeCallback);
                view.setSelected(true);
                return true;
            }
        });
    }



    @Override
    public void gotoCheck(final String inviteCode, final int doWhat, final SignPerson signPerson) {
        secondScreen.dismiss();
        AppExecutors.mainThread.schedule(new Runnable() {
            @Override
            public void run() {
                recognizeFragment.pauseScan();
                removeTopFragment();
                fragmentManager
                        .beginTransaction()
                        .add(R.id.fragContainer,CheckFragment.newInstance(inviteCode,doWhat,signPerson),TAG_CHECK_FRAGMENT)
                        .commit();
            }
        },jumpDelay);

    }

    @Override
    public void gotoOthers(final int doWhat, final List<SignPerson> people, final String idno, final String idname) {
        AppExecutors.mainThread.schedule(new Runnable() {
            @Override
            public void run() {
                if (doWhat==OthersFragment.DO_SIGN_SELF){
                    secondScreen.show();
                }
                recognizeFragment.pauseScan();
                removeTopFragment();
                SignPerson[] signPeople=new SignPerson[people!=null?people.size():0];
                signPeople = people!=null ? people.toArray(signPeople): null;
                fragmentManager
                        .beginTransaction()
                        .add(R.id.fragContainer,OthersFragment.newInstance(doWhat,signPeople,idno,idname), TAG_OTHERS_FRAGMENT)
                        .commit();
            }
        },jumpDelay);

    }

    @Override
    public void gotoWelcome() {
        secondScreen.dismiss();
        recognizeFragment.pauseScan();
        removeTopFragment();
        fragmentManager
                .beginTransaction()
                .add(R.id.fragContainer,new LunchFragment(),TAG_WELCOME_FRAGMENT)
                .commit();
    }

    @Override
    public void gotoRecognize(boolean selfSign) {
        recognizeFragment.resetUI();
        recognizeFragment.resumeScan();
        recognizeFragment.isSelfCheckIn(selfSign);
        removeTopFragment();
    }


    private void removeTopFragment(){

        List<Fragment> fragList = new ArrayList<>();
        Fragment frag = fragmentManager.findFragmentByTag(TAG_WELCOME_FRAGMENT);
        if(frag!=null)fragList.add(frag);
        frag = fragmentManager.findFragmentByTag(TAG_CHECK_FRAGMENT);
        if(frag!=null)fragList.add(frag);
        frag = fragmentManager.findFragmentByTag(TAG_OTHERS_FRAGMENT);
        if(frag!=null)fragList.add(frag);
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        for (int i = 0; i < fragList.size(); i++) {
            transaction.remove(fragList.get(i));
        }
        if (!isDestroyed()) transaction.commitAllowingStateLoss();
    }


    @Override
    public void showToast(final String msg, final int color){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                toastTextView.setVisibility(View.VISIBLE);
                toastTextView.setText(msg);
                toastTextView.setTextColor(color);
                ObjectAnimator.ofFloat(toastTextView, "alpha", 1f).setDuration(500).start();
                Animation a1 = new Animation() {
                    int newLeftMargin = 160;
                    @Override
                    protected void applyTransformation(float interpolatedTime, Transformation t) {
                        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) toastTextView.getLayoutParams();
                        params.bottomMargin = (int)(newLeftMargin * interpolatedTime);
                        toastTextView.setLayoutParams(params);
                    }
                };
                a1.setDuration(500);
                toastTextView.startAnimation(a1);
                AppExecutors.mainThread.schedule(new Runnable() {
                    @Override
                    public void run() {
                        ObjectAnimator.ofFloat(toastTextView, "alpha", 0f).setDuration(500).start();
                        Animation a2 = new Animation() {
                            int newLeftMargin = 160;
                            @Override
                            protected void applyTransformation(float interpolatedTime, Transformation t) {
                                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) toastTextView.getLayoutParams();
                                params.bottomMargin = 160 - (int)(newLeftMargin * interpolatedTime);
                                toastTextView.setLayoutParams(params);
                            }
                        };
                        a2.setDuration(500);
                        toastTextView.startAnimation(a2);
                    }
                },3000);
            }
        });

    }

    @Override
    protected void onStop() {
        secondScreen.dismiss();
        super.onStop();
    }

    @Override
    @WorkerThread
    public void printBill(SignPerson signPerson) {
        billPrinter.printPersonInfo(signPerson,null,null);
    }

    @Override
    @WorkerThread
    public void printBill(SignPerson signPerson, String presenterName, String presenterNo) {
        billPrinter.printPersonInfo(signPerson,presenterName,presenterNo);
    }

    @Override
    protected void onDestroy() {
        billPrinter.release();
        secondScreen.release();
        super.onDestroy();
    }

    private void initSecondScreen(Context context){
        DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
        Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
        if (presentationDisplays.length > 0) {
            Display display = presentationDisplays[0];
            secondScreen = new SecondScreen(context, display);
            router2 = secondScreen;
        }
    }

    public FirstScreenRouter getRouter1() {
        return router1;
    }

    public SecondScreenRouter getRouter2() {
        return router2;
    }

    @Override
    public void onBackPressed() {
        //do nothing
    }
}
